#ifndef _workdir_storage_File_h
#define _workdir_storage_File_h

#include <nemesis.dbos.Object.h>
#include <nemesis.dbos.ObjectFacade.h>
#include <nemesis.dbos.Loader.h>

namespace nemesis {
   namespace dbms {
      class Database;
      class Connection;
   }
   namespace dbos {
      class Repository;
   }
}

namespace workdir {

namespace filesystem {
   class File;
}

namespace storage {

class Directory;

using namespace nemesis;

class File : public dbos::Object, public dbos::ObjectFacade <File> {
public:
   const Directory* getParent () const throw () { return a_parent; }
   const filesystem::File* getFilesystemFile () const throw () { return a_filesystemFile; }
   int getINode () const throw () { return a_inode; }
   
   std::string asString () const throw ();

   static void setup (dbos::Repository&, const int maxSize) throw (RuntimeException);
   static File* instantiate (const filesystem::File*) throw (RuntimeException);
   
   static const char* getStorageAreaName () throw () { return "storage::File"; }   
   static const dbos::Size getMaxSize () throw () { return st_maxSize; }

private:
   class Loader : public dbos::Loader {
   public:
      Loader () : dbos::Loader () {;}

      Loader& setKey (const filesystem::File* file) throw () {
         a_filesystemFile = file;
         return *this; 
      }
      
      const filesystem::File* getFile () const throw () { return a_filesystemFile; }  
      int getINode () const throw () { return a_inode; }

      dbos::Index getIndex () const throw ();
      std::string asString () const throw ();

   private:
      const filesystem::File* a_filesystemFile;
      int a_inode;

      // No usa la base de datos => No requiere dbms::Statement
      dbms::Statement* initialize (dbms::Database&) throw (RuntimeException) { return NULL; }
      bool load (dbms::Connection*, const dbos::StorageArea*) throw (RuntimeException);
   };

   Directory* a_parent;
   const filesystem::File* a_filesystemFile;   
   int a_inode;
   
   static Loader* st_loader;
   static ExclusiveHash <std::string> st_hash;
   static int st_maxSize;
   
   File () : a_parent (NULL) { ; }
   File (const File&);

   void initialize (dbos::Loader& loader) throw (RuntimeException, dbms::DatabaseException);
   void destroy () throw ();

   dbos_declare_object (File);
};

}
}

#endif
